function Messages() { // handles all messaging and error reporting

  // bool for determining if message is allowed to be change e.g. during file uploads, we dont want the message to be changed until done
  this.isLocked = false;
  
  // handles formatting and displaying error messages of varying severity
  this.setError = function(level, reason, msg) {
  
    // level 1: fatal
    // level 2: error
    // level 3: general msg
    
    air.trace(reason); // reason is traced to the debugger / command window its run from
    
    switch(level) {
    
      case 1:
        string = "<span style='font-weight: bold; color: #f00;'>Fatal error: </span>" + msg + "<BR><BR>";
        break;
      
      case 2:
      
        string = "<span style='font-style: italic; color: #f60;'>Error: </span>" + msg + "<BR><BR>";
        break;
    
      case 3:
        string = "Error: " + msg + "<BR>";
        break;
    
    }
    
    this.display(string, 3500); // displays the message
  
  }
  
  // function for handling a very short queue in case unable to display message temporarily
  this.displayAgain = function() {
  
    msgs.display(window.tempString, window.tempTimeout);
  
  }
  
  // display a message
  this.display = function(string, timeout) {
  
    if ((document.getElementById("footer").getElementsByTagName("div")[0].getElementsByTagName("p")[0].innerHTML.length > 0) || (this.isLocked)) { // if not permitted to display
    
      window.tempString = string;
      window.tempTimeout = timeout;
      setTimeout(msgs.displayAgain, 100); // set timeout to try again

    } else {
  
      $("#footer>div>p").fadeOut();

      clearTimeout(window.timer); // clear any timers to hide it

      window.text = string;
      
      window.timer = setTimeout(this.render, page.getLoadspeed()/2);
      
      if (timeout == -1) {
      
        this.isLocked = true; // set it to locked
      
      } else if (timeout != 0) { // if a timeout exists
      
        setTimeout(this.hide, timeout); // set timeout to hide
        
      }
    
    }
  
  }
  
  // actually display on the page
  this.render = function() {
  
    text = window.text;

    $("#footer>div>p").empty().append(text); // append then nicely fade in
    
    $("#footer>div>p").fadeIn();
  
  }
  
  // easily add something to the end of the message
  this.append = function(string) {
  
    $("#footer>div>p").append(string);
  
  }

  // quickly swap something into the message
  this.swap = function(string) {
  
    $("#footer>div>p").empty().append(string);
  
  }
  
  // set message to writable again
  this.unlock = function() {

    this.isLocked = false;
    
    this.hide();
    
  }
  
  // hide the message
  this.hide = function() {
  
    if (!this.isLocked) {
    
      clearTimeout(window.timer);

      $("#footer>div>p").fadeOut();
      
      setTimeout(msgs.clear, 275); // allow fadeout before clear

    }
  
  }
  
  // actually clear the message
  this.clear = function() {
  
    $("#footer>div>p").empty();
  
  }

}